package ink.tsg.postgresql.handler;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Properties;

/**
 * @author geo_tsg
 * @version 1.0.0
 * @ClassName MybatisInterceptor.java
 * @Description mybatis插件
 * @createTime 2021-11-15
 */
/**
 * @Intercepts 注解标记这是一个拦截器,其中可以指定多个@Signature
 * @Signature 指定该拦截器拦截的是四大对象中的哪个方法
 *      type：拦截器的四大对象的类型
 *      method：拦截器的方法，方法名
 *      args：入参的类型，可以是多个，根据方法的参数指定，以此来区分方法的重载
 */
@Intercepts(
        {
                @Signature(type = Executor.class,method ="query",args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
        }
)
public class MybatisInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("拦截器执行："+invocation.getTarget());
        Object[] args = invocation.getArgs();
        Object parameter = args[1];
        List<Object> result = (List<Object>) invocation.proceed();
        result.forEach(item ->{
            Class<?> aClass = item.getClass();
            /**
             * 内省机制
             */
            try {
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor("name", aClass);
                Method setMethod = propertyDescriptor.getWriteMethod();
                setMethod.invoke(item, "erer");
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        //如果没有特殊定制，直接使用Plugin这个工具类返回一个代理对象即可
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
